import 'dart:io';

import 'package:bot_toast/bot_toast.dart';
import 'package:demo/constants/route_location.dart';
import 'package:demo/core/router/app_router_observer.dart';
import 'package:demo/route/route_application.dart';
import 'package:demo/utils/toast.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

class AppRouterDelegate extends RouterDelegate<RouteSettings> with PopNavigatorRouterDelegateMixin, ChangeNotifier {
  /// 路由的唯一key
  static final GlobalKey<NavigatorState> _stackRouteKey = GlobalKey<NavigatorState>();

  /// 路由栈
  final List<Page<dynamic>> _stack = [];

  /// 长度
  int get length => _stack.length;

  /// 判空
  bool isEmpty() => _stack.isEmpty;

  /// 获取路由栈的地址集合
  List<String>? get allPageName => _stack.map<String>((e) => e.name as String).toList();

  /// 直接引用对应的路由代理
  static AppRouterDelegate of() {
    return Router.of(_stackRouteKey.currentContext!).routerDelegate as AppRouterDelegate;
  }

  /// 最近一次点击返回键事件，用于安卓点击2次退出app
  DateTime? _lastPressTime;

  @override
  GlobalKey<NavigatorState> get navigatorKey => _stackRouteKey;

  @override
  RouteSettings? get currentConfiguration => _stack.isNotEmpty ? _stack.last as RouteSettings : null;

  /// app设置根会触发
  @override
  Future<void> setNewRoutePath(configuration) async {
    if (kIsWeb) {
      // 针对web可以重置也可以push
      return;
    }
    _stack
      ..clear()
      ..add(
        RouteApplication.instance.getRoute(
          configuration.name!,
          params: configuration.arguments as Map<String, dynamic>?,
        ),
      );
    notifyListeners();
    return SynchronousFuture<void>(null);
  }

  @override
  Future<bool> popRoute() {
    if (_stack.length > 1) {
      return super.popRoute();
    }
    if (Platform.isAndroid) {
      if (_lastPressTime == null || DateTime.now().difference(_lastPressTime!) > Duration(seconds: 1)) {
        _lastPressTime = DateTime.now();
        ToastUtils.showText(text: "再按一次退出程序");
        return SynchronousFuture<bool>(true);
      }
    }
    return super.popRoute();
  }

  /// 跳转页面
  Future<void> push(
    String pageName, {
    Map<String, dynamic>? params,
    RouteStyle style = RouteStyle.IOS,
    RouteTransitionsBuilder? customTransitionsBuilder,
  }) async {
    if (_stack.isNotEmpty) {
      _stack.add(
        RouteApplication.instance.getRoute(
          pageName,
          params: params,
          style: style,
          customTransitionsBuilder: customTransitionsBuilder,
        ),
      );
      notifyListeners();
    }
    return SynchronousFuture<void>(null);
  }

  /// 后退页面
  Future<bool> pop<T>([T? result]) async {
    return navigatorKey.currentState!.maybePop<T>(result);
  }

  /// 替换当前页面
  Future<void> replace(String pageName) async {
    if (_stack.isNotEmpty) {
      _stack.replaceRange(_stack.length - 1, _stack.length, [
        RouteApplication.instance.getRoute(pageName),
      ]);
    }
    return SynchronousFuture<void>(null);
  }

  /// 删除指定的某些页面
  Future<void> popWhere(List<String> pageNameList) async {
    if (_stack.isNotEmpty && pageNameList.length > 0) {
      _stack.removeWhere((Page<dynamic> p) => pageNameList.contains(p.name));
      notifyListeners();
    }
    return SynchronousFuture<void>(null);
  }

  /// 只留其他首页，其他页面关闭
  void get popExceptRoot => popWhere(const [ROOT_LOCATION]);

  /// 设置根页面
  Future<void> setRoot(
    String location, {
    Map<String, dynamic>? params,
  }) async {
    await setNewRoutePath(RouteSettings(name: location, arguments: params));
  }

  /// 后退路由回掉
  bool _onPopPage(Route<dynamic> route, dynamic result) {
    if (!route.didPop(result)) {
      return false;
    }
    if (_stack.isNotEmpty) {
      _stack.removeLast();
      notifyListeners();
    }
    return true;
  }

  @override
  Widget build(BuildContext context) {
    return BotToastInit()(
      context,
      Navigator(
        key: navigatorKey,
        observers: [
          BotToastNavigatorObserver(),
          AppRouterObserver(),
        ],
        pages: List.of(_stack),
        onPopPage: _onPopPage,
        reportsRouteUpdateToEngine: kIsWeb,
      ),
    );
  }
}
